#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: Polyfunctional.py 274 2010-09-29 13:16:14Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses, pythonequations.EquationsForPolyfunctionals
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class Polyfunctional3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="User-Selectable Polyfunctional"
    _HTML = "z = user-selectable function"
    coefficientDesignatorTuple = ()
    polyfunctionalFlag = 1
    LinearSSQSolverFlag = 1
    EquationListForPolyfunctional = []
    EquationListForPolyfunctional.append(pythonequations.EquationsForPolyfunctionals.GenerateListForPolyfunctionals('x', 'x_in'))
    EquationListForPolyfunctional.append(pythonequations.EquationsForPolyfunctionals.GenerateListForPolyfunctionals('y', 'y_in'))
    Polyfun3DEqList = pythonequations.EquationsForPolyfunctionals.GenerateListForPolyfunctionals('unused', 'unused')
    function_cpp_code = 'temp = 0.0;\nfor (int k=0; k<_nc; k++)\n\ttemp += coeff[k] * _id[_cwo[k]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        for i in range(len(self.Polyfun3DFlags)):
            if self.Polyfun3DFlags[i][0] > 0 or self.Polyfun3DFlags[i][1] > 0:
                self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Polyfunctional3D(NameOrValueFlag=1, args=[self.Polyfun3DFlags[i][0], self.Polyfun3DFlags[i][1]]), [self.Polyfun3DFlags[i][0], self.Polyfun3DFlags[i][1]]])
        if [0,0] in self.Polyfun3DFlags:
            self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Polyfunctional3D(NameOrValueFlag=1, args=[0,0]), [0,0]])

    def GetSpecificJavascript(self):
        if self.SpecificJavascript == None:
            self.SpecificJavascript = self.ReadTextFile('FunctionMatrix3D.js')
        return self.SpecificJavascript

    def SpecificCodeCPP(self):
        s = ""
        count = 0
        for i in range(len(self.coefficientArray)):
            if self.Polyfun3DFlags[i][0] == 0 and self.Polyfun3DFlags[i][1] == 0:
                continue;
            if self.Polyfun3DFlags[i][0] > 0 and self.Polyfun3DFlags[i][1] == 0:
                s += "\ttemp += " + self.coefficientDesignatorTuple[count] + " * " + self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]].CPP + ";\n"
            elif self.Polyfun3DFlags[i][0] == 0 and self.Polyfun3DFlags[i][1] > 0:
                s += "\ttemp += " + self.coefficientDesignatorTuple[count] + " * " + self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]].CPP + ";\n"
            elif self.Polyfun3DFlags[i][0] > 0 and self.Polyfun3DFlags[i][1] > 0:
                s += "\ttemp += " + self.coefficientDesignatorTuple[count] + " * " + self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]].CPP + " * " + self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]].CPP + ";\n"
            count += 1
        if [0,0] in self.Polyfun3DFlags:
            s += "\ttemp += " + self.coefficientDesignatorTuple[count] + ";\n"
        return s


    def Initialize(self):
        self.coefficientDesignatorTuple = ()
        self.additionalDesignatorList = []
        
        if len(self.Polyfun3DFlags) == 0:
            self._HTML = "z = user-selectable function"
            return

        for i in range(len(self.Polyfun3DFlags)-1):
            self.coefficientDesignatorTuple += (pythonequations.EquationBaseClasses.Equation.ascii[i]),
        if [0,0] in self.Polyfun3DFlags:
            self.coefficientDesignatorTuple += ('Offset'),
        else:
            self.coefficientDesignatorTuple += (pythonequations.EquationBaseClasses.Equation.ascii[len(self.Polyfun3DFlags)-1]),

        self._HTML = "</B><B>z = " # turn off any preceding bolding
        count = 0
        for i in range(len(self.Polyfun3DFlags)):
            if self.Polyfun3DFlags[i][0] == 0 and self.Polyfun3DFlags[i][1] == 0:
                continue
            elif self.Polyfun3DFlags[i][0] > 0 and self.Polyfun3DFlags[i][1] == 0:
                self._HTML += pythonequations.EquationBaseClasses.Equation.ascii[count] + '(</B>&nbsp;' + self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]]._HTML + '&nbsp;<B>)'
            elif self.Polyfun3DFlags[i][0] == 0 and self.Polyfun3DFlags[i][1] > 0:
                self._HTML += pythonequations.EquationBaseClasses.Equation.ascii[count] + '(</B>&nbsp;' + self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]]._HTML + '&nbsp;<B>)'
            else:
                self._HTML += pythonequations.EquationBaseClasses.Equation.ascii[count] + '(</B>&nbsp;' + self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]]._HTML + self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]]._HTML + '&nbsp;<B>)'
            if i < len(self.Polyfun3DFlags)-1 or [0,0] in self.Polyfun3DFlags:
                self._HTML += ' + '
            count += 1

        if [0,0] in self.Polyfun3DFlags:
            self._HTML += "Offset"

        self._HTML += '</B>'

        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        self.CannotAcceptDataWithZeroX = False
        self.CannotAcceptDataWithPositiveX = False
        self.CannotAcceptDataWithNegativeX = False
        self.CannotAcceptDataWithZeroY = False
        self.CannotAcceptDataWithPositiveY = False
        self.CannotAcceptDataWithNegativeY = False
        for i in range(len(self.Polyfun3DFlags)-1):
            self.CannotAcceptDataWithZeroX |= self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]].CannotAcceptDataWithZeroX
            self.CannotAcceptDataWithPositiveX |= self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]].CannotAcceptDataWithPositiveX
            self.CannotAcceptDataWithNegativeX |= self.EquationListForPolyfunctional[0][self.Polyfun3DFlags[i][0]].CannotAcceptDataWithNegativeX
            self.CannotAcceptDataWithZeroY |= self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]].CannotAcceptDataWithZeroY
            self.CannotAcceptDataWithPositiveY |= self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]].CannotAcceptDataWithPositiveY
            self.CannotAcceptDataWithNegativeY |= self.EquationListForPolyfunctional[1][self.Polyfun3DFlags[i][1]].CannotAcceptDataWithNegativeY
